#include <stdio.h>
#include <string.h>
#include "Md5.h"
#include "Auth.h"
#include "MQTT/MQTTError.h"
#include "Core/Interface.h"
#include "Core/Utils/Number.h"
#include "Core/Utils/String.h"

int32_t authUsername(char **dest, AiotEntity *entity) {

    *dest = getSystemInterface()->memMalloc(128);
    memset(*dest,0x00,128);

    if (entity->registerMode == thirdTuple) {
        snprintf(*dest,127,"2|%s|%s",entity->aiotAccess.productKey, entity->aiotAccess.deviceKey);
    } else {
        snprintf(*dest,127,"1|%s|%s",entity->aiotDeviceInfo.productKey,entity->aiotDeviceInfo.deviceNo);
    }

    return aiotSuccess;
}

int32_t authPassword(char **dest, AiotEntity *entity) {

    char sign[64] = {0};
    uint64_t timestamp = getSystemInterface()->getTimestamp();
    char timeString[32] = {0},plainText[256] = {0};
    uint8_t timeStrLen = 0;
    uint64ToString(timestamp,timeString,&timeStrLen);

    if (entity->registerMode == thirdTuple) {
        AiotDeviceInfo* access = &entity->aiotAccess;
        snprintf(plainText,255,"%s%s%s%s",access->productKey,access->deviceKey,timeString,access->secretKey);
    } else {
        AiotProductInfo* device = &entity->aiotDeviceInfo;
        snprintf(plainText,255,"%s%s%s%s",device->productKey,device->deviceNo,timeString,device->secretKey);
    }

    md5sum(plainText,sign, sizeof(sign));
    memset(plainText,0x00, sizeof(plainText));
    if (entity->registerMode == thirdTuple) {
        AiotDeviceInfo* access = &entity->aiotAccess;
        snprintf(plainText,255,"productKey=%s&deviceName=%s&timestamp=%s&sign=%s&registerType=2",access->productKey,access->deviceKey,timeString,sign);
    } else {
        AiotProductInfo* device = &entity->aiotDeviceInfo;
        snprintf(plainText,255,"productKey=%s&deviceSN=%s&timestamp=%s&sign=%s&registerType=1",device->productKey,device->deviceNo,timeString,sign);
    }

    *dest = getSystemInterface()->memMalloc(256);
    if (*dest == nullptr) {
        return memoryMallocFailed;
    }

    memset(*dest, 0,256);
    memcpy(*dest,plainText,strlen(plainText));
    return aiotSuccess;
}

int32_t authClientId(char **dest, AiotEntity *entity, char *extClientId) {

    uint64_t timestamp = getSystemInterface()->getTimestamp();
    char timeString[32] = {0};
    uint8_t timeStrLen = 0;
    uint64ToString(timestamp,timeString,&timeStrLen);

    if (entity->registerMode == deviceNumber) {
        AiotProductInfo* device = &entity->aiotDeviceInfo;
        char *src[] = {device->deviceNo,timeString};
        return stringSprintf(dest,"%s%s", src, sizeof(src)/sizeof(char *));
//        char *src[] = {device->productKey,device->deviceNo,timeString,extClientId};
        return stringSprintf(dest,"1|%s.%s|timestamp=%s,sign=md5,%s",src, sizeof(src)/sizeof(char *));
    } else {
        AiotDeviceInfo* access = &entity->aiotAccess;
        char *src[] = {access->deviceKey,timeString};
        return stringSprintf(dest,"%s%s", src, sizeof(src)/sizeof(char *));
//        return stringSprintf(dest,"2|%s.%s|timestamp=%s,sign=md5,%s",src, sizeof(src)/sizeof(char *));
    }
}
